﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace DotNETX.Utility
{
    public class ProcessUtils
    {
        /// <summary> 
        /// 运行CMD命令 
        /// </summary> 
        /// <param name="cmd">命令</param> 
        /// <param name="timeout">超时时间 毫秒</param> 
        /// <returns></returns> 
        public static void Cmd(string[] cmd, string workingdir = null, int timeout = 0)
        {
            Process p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            // 将此属性设置为 false 使您能够重定向输入流、输出流和错误流。
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;
            if (string.IsNullOrEmpty(workingdir)) p.StartInfo.WorkingDirectory = workingdir;
            p.Start();
            p.StandardInput.AutoFlush = true;
            for (int i = 0; i < cmd.Length; i++)
            {
                p.StandardInput.WriteLine(cmd[i].ToString());
            }
            p.StandardInput.WriteLine("exit");
            // string strRst = p.StandardOutput.ReadToEnd();
            if (timeout > 0) p.WaitForExit(timeout);
            else p.WaitForExit();
            p.Close();
            return;
        }

        /// <summary>
        /// 开启进程
        /// </summary>
        /// <param name="filepath"></param>
        /// <param name="args"></param>
        /// <param name="workingdir"></param>
        /// <returns></returns>
        public static Process StartProcess(string filepath, string args = null, bool useShellExcute = true, string workingdir = null)
        {
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.FileName = filepath;
            startInfo.Arguments = args;
            // 使用操作系统外壳程序启动进程时，您能够使用 Process 组件启动任何文档（可以是任何与可执行文件关联的、拥有默认打开操作的注册文件类型），并对该文件执行操作（如打印）。当 UseShellExecute 为 false 时，使用 Process 组件仅能启动可执行文件。
            startInfo.UseShellExecute = useShellExcute;
            // WorkingDirectory 属性的行为在 UseShellExecute 为 true 并当 UseShellExecute 为 false 时是不同的。
            // 当 UseShellExecute 为 true 时，WorkingDirectory 属性指定可执行文件的位置。如果 WorkingDirectory 是空字符串，则认为当前目录包含可执行文件。
            // 当 UseShellExecute 为 false 时，不使用 WorkingDirectory 属性查找可执行文件。相反，它被已启动的进程使用，并且只在新进程的上下文中有意义。
            startInfo.WorkingDirectory = workingdir;
            Process proc = Process.Start(startInfo);
            return proc;
        }

        /// <summary> 
        /// 关闭进程 
        /// <param name="ProcName">进程名称</param> 
        /// <returns></returns> 
        public static bool CloseProcess(string procName)
        {
            bool result = false;
            foreach (System.Diagnostics.Process proc in System.Diagnostics.Process.GetProcessesByName(procName))
            {
                // 当发送关闭窗口命令无效时强行结束进程 
                if (!proc.CloseMainWindow()) proc.Kill();
                result = true;
            }
            //System.Collections.ArrayList procList = new System.Collections.ArrayList(); 
            //string tempName = ""; 
            //int begpos; 
            //int endpos;
            //foreach (System.Diagnostics.Process thisProc in System.Diagnostics.Process.GetProcesses())
            //{
            //    tempName = thisProc.ToString();
            //    begpos = tempName.IndexOf("(") + 1;
            //    endpos = tempName.IndexOf(")");
            //    tempName = tempName.Substring(begpos, endpos - begpos);
            //    procList.Add(tempName);
            //    if (tempName == procName)
            //    {
            //        if (!thisProc.CloseMainWindow()) thisProc.Kill();
            //        // 当发送关闭窗口命令无效时强行结束进程 
            //        result = true;
            //    }
            //}
            return result;
        }

        public static bool CloseProcess(int pID)
        {
            bool result = false;
            Process proc = System.Diagnostics.Process.GetProcessById(pID);
            if (proc != null)
            {
                if (!proc.CloseMainWindow()) proc.Kill();
                // 当发送关闭窗口命令无效时强行结束进程 
                result = true;
            }
            return result;
        }

    }
}
